package weeny.face;

import static java.awt.event.ActionEvent.ACTION_PERFORMED;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;

import weeny.util.logs.Debug;

public class LateSpinner extends JSpinner{

	public LateSpinner() {
		getComponent(0).addMouseListener(mouseListener);
		getComponent(1).addMouseListener(mouseListener);
		setBorder(null);
		getEditor().getComponent(0).removeKeyListener(keyListener);
		getEditor().getComponent(0).addKeyListener(keyListener);
	}
	protected JComponent createEditor(SpinnerModel model) {
		return new NumberEditor(this);
	}
	public LateSpinner(SpinnerModel model){
		super(model);
		getComponent(0).addMouseListener(mouseListener);
		getComponent(1).addMouseListener(mouseListener);
		getEditor().getComponent(0).removeKeyListener(keyListener);
		getEditor().getComponent(0).addKeyListener(keyListener);
		setBorder(null);
	}
	@Override
	public void setModel(SpinnerModel model) {
		getEditor().getComponent(0).removeKeyListener(keyListener);
		super.setModel(model);
		getEditor().getComponent(0).addKeyListener(keyListener);
	}
	protected KeyAdapter keyListener = new KeyAdapter(){
		@Override
		public void keyPressed(KeyEvent e) {
			if (e.getKeyCode() != 10) {
				return;
			}
			Object current = getValue();
			JTextField fld = (JTextField) getEditor().getComponent(0);
			try {
				commitEdit();
			} catch (ParseException e1) {
				Debug.prob("Illegal "+fld.getText()+", restore it");
				fld.setText(current.toString());
				setValue(current);
			}
			Comparable value = (Comparable) getValue();
			SpinnerModel model = getModel();
			if (model instanceof SpinnerNumberModel) {
				SpinnerNumberModel snm = (SpinnerNumberModel) model;
				Comparable max = snm.getMaximum();
				Comparable min = snm.getMinimum();
				if (max != null && max.compareTo(value)<0){
					value = max;
					Debug.info("Above max: "+max);
				}
				if (min != null && min.compareTo(value)>0){
					value = min;
					Debug.info("Below min: "+min);
				}
			}
			fireActionEvent(e.getModifiers());
		}
	};
	public void addActionListener(ActionListener lsn){
		if (!listeners.contains(lsn)) {
			listeners.add(lsn);
		}
	}
	public boolean removeListener(ActionListener lsn){
		return listeners.remove(lsn);
	}

	protected List<ActionListener> listeners = new ArrayList<ActionListener>();
	protected void fireActionEvent(int modifier){
		ActionEvent ae = new ActionEvent(this, ACTION_PERFORMED, "", modifier);
		for(ActionListener al : listeners){
			al.actionPerformed(ae);
		}
	}
	protected MouseAdapter mouseListener = new MouseAdapter(){
		@Override
		public void mouseReleased(MouseEvent e) {
			if (e.getButton() == 1)
				fireActionEvent(e.getModifiers());
		}
	};
}
